Using Multiple Pseudo-Classes in CSS
In CSS, you can combine multiple pseudo-classes to apply styles to elements that satisfy all of the specified conditions simultaneously. This allows for more precise and dynamic styling.
Chain pseudo-classes after a selector without spaces (e.g., a:hover:active).
You can mix structural and dynamic pseudo-classes (e.g., li:first-child:hover).
Pseudo-classes can also be combined with the :not() pseudo-class for exclusions.
In this example, only the first list item changes color on hover. Checked checkboxes change accent color when hovered, and enabled buttons change background when hovered, showing how multiple pseudo-classes can work together.
Combine pseudo-classes logically to target elements accurately without adding extra HTML classes.
Keep chains readable and avoid over-complicating selectors.
Test combined pseudo-classes across browsers to ensure consistent behavior.
Use transitions to make dynamic changes smooth for better UX.
How would you style a button so it only shows a background color when the user hovers over it AND it’s focused, but not when it’s disabled?
What happens if you write .btn:hover:focus instead of .btn:focus:hover — does it matter, and why?
You have a list item that’s supposed to turn red when hovered and also be the first child — how would you write that selector?
A user reports that a form input’s focus state isn’t working when they tab to it — you notice it’s styled with :focus:hover, but the hover never triggers. What’s likely wrong?
You’re building a navigation menu where links should highlight on hover, but not if they’re the active page — how would you combine pseudo-classes to handle this without adding extra classes?
A component works fine in Chrome but breaks in Safari when using :nth-child(2n+1):not(.hidden) — what could be the issue, and how would you debug it?
You’re designing a reusable card component that needs to support complex state combinations like :hover:not(.loading):focus-visible — how do you ensure this doesn’t bloat your CSS or create specificity wars across teams?
A legacy UI has 20+ pseudo-class combinations scattered across files, causing unpredictable overrides. How would you refactor this for maintainability without breaking existing behavior?
How would you architect a design system where pseudo-class combinations are predictable across components, and how do you enforce that consistency at scale?
You’re migrating a legacy CSS codebase that relies heavily on pseudo-class chains for state management — how do you decide whether to keep them, replace them with attributes, or move to a CSS-in-JS approach without breaking accessibility or performance?
How would you design a CSS architecture that allows product teams to safely extend pseudo-class combinations without introducing specificity conflicts, especially when teams use different styling methodologies?
When scaling a global design system, how do you balance the expressiveness of pseudo-class chaining against the risk of unintended side effects across thousands of components, and what tooling or governance do you put in place?